<template>
  <!-- 查询表单 -->
  <a-collapse v-model:activeKey="activeKey" :bordered="false">
    <a-collapse-panel key="1" :style="customStyle" header="物品管理-查询">
      <a-row>
        <a-col :span="22">
          <a-form ref="queryFormRef" :model="queryFormState">
            <a-row :gutter="16">
              <a-col :span="12">
                <a-form-item label="物品名" name="name">
                  <a-input v-model:value="queryFormState.name" placeholder="请输入物品名" />
                </a-form-item>
              </a-col>
              <a-col :span="12">
                <a-form-item label="创建时间" name="createdAt">
                  <a-range-picker style="width: 100%" @change="created" />
                </a-form-item>
              </a-col>
              <a-col :span="12">
                <a-form-item label="状态" name="status">
                  <a-select
                    v-model:value="queryFormState.status"
                    :filter-option="filterOption"
                    :options="statusOptions"
                    placeholder="请选择状态"
                  />
                </a-form-item>
              </a-col>
              <a-col :span="12">
                <a-form-item label="更新时间" name="updatedAt">
                  <a-range-picker style="width: 100%" @change="updated" />
                </a-form-item>
              </a-col>
            </a-row>
          </a-form>
        </a-col>
        <a-divider style="height: 80px" type="vertical" />
        <a-col :span="1">
          <a-space :size="22" direction="vertical">
            <a-button type="primary" @click="onQuery">
              <template #icon>
                <SearchOutlined />
              </template>
              查询
            </a-button>
            <a-button @click="onReset">
              <template #icon>
                <ReloadOutlined />
              </template>
              重置
            </a-button>
          </a-space>
        </a-col>
      </a-row>
    </a-collapse-panel>
  </a-collapse>
  <!-- 数据表格 -->
  <a-card size="small">
    <a-button size="small" style="margin-bottom: 10px" type="primary" @click="modalVisible = true">
      <template #icon>
        <PlusOutlined />
      </template>
      添加
    </a-button>
    <a-button
      size="small"
      type="primary"
      danger
      :disabled="!hasSelected"
      :loading="rowSelectionState.loading"
      @click="start"
      style="margin-left: 10px"
    >
      <template #icon>
        <DeleteOutlined />
      </template>
      删除
    </a-button>
    <span style="margin-left: 8px">
      <template v-if="hasSelected">
        {{ `选择了 ${rowSelectionState.selectedRowKeys.length} 条数据` }}
      </template>
    </span>
    <!-- 表格 -->
    <a-table
      v-model:pagination="pagination"
      :columns="columns"
      :data-source="dataSource"
      :loading="loading"
      :scroll="{ x: '150%', y: 360 }"
      bordered
      rowKey="id"
      :row-selection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
      @change="handleTableChange"
    >
      <template #bodyCell="{ column, record }">
        <!-- 物品图片 -->
        <template v-if="column.dataIndex === 'imgList'">
          <a-image-preview-group>
            <template v-for="(img, index) in record.imgList" :key="index">
              <a-image v-if="index === 0" :src="img" />
              <a-image v-else :src="img" style="display: none" />
            </template>
          </a-image-preview-group>
        </template>
        <!-- 是否禁用 -->
        <template v-if="column.dataIndex === 'status'">
          <template v-if="record.status === 0">
            <div class="enable"></div>
          </template>
          <template v-else>
            <div class="disabled"></div>
          </template>
        </template>
        <!-- 操作 -->
        <template v-if="column.dataIndex === 'operations'">
          <div class="action">
            <a-button size="small" type="primary" @click="onEdit(record.id)">
              <template #icon>
                <EditOutlined />
              </template>
            </a-button>
            <a-popconfirm cancel-text="×" ok-text="√" title="删除？" @confirm="confirm">
              <a-button danger size="small" type="primary" @click="onDelete(record.id)">
                <template #icon>
                  <DeleteOutlined />
                </template>
              </a-button>
            </a-popconfirm>
          </div>
        </template>
      </template>
    </a-table>
  </a-card>
  <!-- 新增数据模态框 -->
  <a-modal v-model:visible="modalVisible" title="添加物品" @cancel="handleCancel" @ok="handleOk">
    <a-form ref="addFormRef" :model="addFormState" :rules="addFormRules" layout="vertical">
      <a-row :gutter="16">
        <a-col :span="12">
          <a-form-item label="物品名" name="name">
            <a-input v-model:value="addFormState.name" placeholder="请输入物品名" />
          </a-form-item>
        </a-col>
        <a-col :span="12">
          <a-form-item label="租赁价格" name="leasingPrice">
            <a-input-number
              prefix="￥"
              style="width: 100%"
              :min="0"
              :step="0.01"
              :formatter="(value:number) => `${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')"
              :parser="(value:string) => value.replace(/\$\s?|(,*)/g, '')"
              v-model:value="addFormState.leasingPrice"
              placeholder="请输入租赁价格"
            ></a-input-number>
          </a-form-item>
        </a-col>
      </a-row>
      <a-row :gutter="16">
        <a-col :span="12">
          <a-form-item label="状态" name="status">
            <a-select
              v-model:value="addFormState.status"
              :options="statusOptions"
              placeholder="请选择是否禁用"
            />
          </a-form-item>
        </a-col>
        <a-col :span="12">
          <a-form-item label="分类" name="categoryId">
            <a-select
              v-model:value="addFormState.categoryId"
              :options="categoryOptions"
              placeholder="请选择物品分类"
            />
          </a-form-item>
        </a-col>
      </a-row>
      <a-row :gutter="16">
        <a-col :span="24">
          <a-form-item label="描述" name="description">
            <a-textarea v-model:value="addFormState.description" placeholder="请输入描述" />
          </a-form-item>
        </a-col>
      </a-row>
      <a-row :gutter="16">
        <a-col :span="24">
          <a-form-item label="物品图片" name="imgList">
            <a-form-item-rest>
              <a-input
                v-for="(img, index) in addFormState.imgList"
                :key="index"
                :value="img"
                hidden
              />
            </a-form-item-rest>
            <a-upload
              v-model:file-list="fileList"
              name="file"
              list-type="picture-card"
              :headers="{ Authorization: getToken() }"
              action="/api/file/uploadFile"
              multiple
              :maxCount="6"
              @change="handleChange"
              @remove="handleRemove"
            >
              <div v-if="fileList.length < 6">
                <PlusOutlined />
                <div style="margin-top: 8px">Upload</div>
              </div>
            </a-upload>
          </a-form-item>
        </a-col>
      </a-row>
    </a-form>
  </a-modal>
  <!-- 更新数据抽屉 -->
  <a-drawer
    :body-style="{ paddingBottom: '80px' }"
    :footer-style="{ textAlign: 'right' }"
    :visible="drawerVisible"
    :width="720"
    title="编辑物品信息"
    @close="onClose"
  >
    <a-form ref="updateFormRef" :model="updateFormState" :rules="updateFormRules" layout="vertical">
      <a-row :gutter="16">
        <a-col :span="12">
          <a-form-item label="物品名" name="name">
            <a-input v-model:value="updateFormState.name" placeholder="请输入物品名" />
          </a-form-item>
        </a-col>
        <a-col :span="12">
          <a-form-item label="租赁价格" name="leasingPrice">
            <a-input
              v-model:value="updateFormState.leasingPrice"
              placeholder="请输入租赁价格"
            ></a-input>
          </a-form-item>
        </a-col>
      </a-row>
      <a-row :gutter="16">
        <a-col :span="12">
          <a-form-item label="状态" name="status">
            <a-select
              v-model:value="updateFormState.status"
              :options="statusOptions"
              placeholder="请选择状态"
            />
          </a-form-item>
        </a-col>
        <a-col :span="12">
          <a-form-item label="物品分类" name="categoryId">
            <a-select
              v-model:value="updateFormState.categoryId"
              :options="categoryOptions"
              placeholder="请选择状态"
            />
          </a-form-item>
        </a-col>
      </a-row>
      <a-row :gutter="16">
        <a-col :span="24">
          <a-form-item label="描述" name="description">
            <a-textarea v-model:value="updateFormState.description" placeholder="请输入描述" />
          </a-form-item>
        </a-col>
      </a-row>
      <a-row :gutter="16">
        <a-col :span="24">
          <a-form-item label="物品图片" name="imgList">
            <a-form-item-rest>
              <a-input
                v-for="(img, index) in updateFormState.imgList"
                :key="index"
                :value="img"
                hidden
              />
            </a-form-item-rest>
            <a-upload
              v-model:file-list="fileList"
              name="file"
              list-type="picture-card"
              :headers="{ Authorization: getToken() }"
              action="/api/file/uploadFile"
              multiple
              :maxCount="6"
              @change="handleChange"
              @remove="handleRemove"
            >
              <div v-if="fileList.length < 6">
                <PlusOutlined />
                <div style="margin-top: 8px">Upload</div>
              </div>
            </a-upload>
          </a-form-item>
        </a-col>
      </a-row>
    </a-form>
    <template #extra>
      <a-space>
        <a-button @click="onClose">取消</a-button>
        <a-button type="primary" @click="onFinish">提交</a-button>
      </a-space>
    </template>
  </a-drawer>
</template>
<script lang="ts" setup>
import { computed, onMounted, reactive, ref, toRefs } from 'vue'
import type {
  FormInstance,
  TableColumnType,
  UploadChangeParam,
  TableProps,
  UploadFile
} from 'ant-design-vue'
import { message } from 'ant-design-vue'
import { usePagination } from 'vue-request'
import {
  addArticle,
  deleteByIds,
  getArticleById,
  queryArticleList,
  updateArticle
} from '@/api/article'
import type { Rule } from 'ant-design-vue/lib/form'
import type { AddArticleDTO, QueryArticleDTO, UpdateArticleDTO, ArticleDTO } from '@/types/article'
import type { IntervalStrDTO } from '@/types/global'
import { queryAllCategory } from '@/api/category'
import { getToken } from '@/utils/auth'

// 下拉列表自定义样式
const customStyle = 'background: #ffffff;' + 'margin-bottom: 10px;' + 'border: none;'

// 状态选择
const statusOptions = computed(() => [
  {
    label: '正常',
    value: 0
  },
  {
    label: '禁用',
    value: 1
  }
])

const categoryOptions = reactive<{ label: string; value: number }[]>([])

onMounted(() => {
  queryAllCategory().then((res) => {
    res.data.data.forEach((category) => {
      categoryOptions.push({
        label: category.name,
        value: category.id
      })
    })
  })
})

// todo 多选框搜索，需要支持中文筛选
const filterOption = (input: string, option: any) => {
  return option.value.toLowerCase().indexOf(input.toLowerCase()) >= 0
}
const queryFormRef = ref<FormInstance>()
const queryFormState = reactive<QueryArticleDTO & IntervalStrDTO>({})
// 查询
const onQuery = () => {
  run({
    ...queryFormState
  })
}
// 重置
const onReset = () => {
  queryFormRef.value?.resetFields()
}

// 选择更新时间间隔
const updated = (date: any, dateString: (string | undefined)[]) => {
  queryFormState.updatedAtStart = dateString[0]
  queryFormState.updatedAtEnd = dateString[1]
}
// 选择创建时间间隔
const created = (date: any, dateString: (string | undefined)[]) => {
  queryFormState.createdAtStart = dateString[0]
  queryFormState.createdAtEnd = dateString[1]
}

// 表格列配置
const columns: TableColumnType<ArticleDTO>[] = [
  {
    title: 'ID',
    dataIndex: 'id',
    fixed: 'left',
    align: 'center',
    sorter: true,
    width: 60
  },
  {
    title: '物品名',
    dataIndex: 'name',
    align: 'center',
    fixed: 'left',
    sorter: true
  },
  {
    title: '租赁价格',
    dataIndex: 'leasingPrice',
    align: 'center',
    sorter: true
  },
  {
    title: '物品描述',
    dataIndex: 'description',
    align: 'center',
    ellipsis: true
  },
  {
    title: '分类',
    dataIndex: 'categoryName',
    align: 'center'
  },
  {
    title: '状态',
    dataIndex: 'status',
    align: 'center'
  },
  {
    title: '发布人',
    dataIndex: 'nickname',
    align: 'center'
  },
  {
    title: '图片',
    dataIndex: 'imgList',
    align: 'center'
  },
  {
    title: '创建时间',
    dataIndex: 'createdAt',
    align: 'center',
    sorter: true,
    width: 200
  },
  {
    title: '更新时间',
    dataIndex: 'updatedAt',
    align: 'center',
    sorter: true,
    width: 200
  },
  {
    title: '操作',
    dataIndex: 'operations',
    fixed: 'right',
    align: 'center'
  }
]

const activeKey = ref(['1'])

// 处理表格变化
const handleTableChange: TableProps['onChange'] = (pagination, filters: any, sorter: any) => {
  run({
    current: pagination.current,
    pageSize: pagination.pageSize,
    sortField: sorter.field,
    sortOrder: sorter.order,
    ...queryFormState
  })
}

const { data, total, run, loading, current, pageSize } = usePagination(queryArticleList, {
  defaultParams: [
    {
      current: 1,
      pageSize: 10
    }
  ],
  pagination: {
    currentKey: 'current',
    pageSizeKey: 'pageSize',
    totalKey: 'data.data.total'
  }
})

// 分页数据
const pagination = computed(() => ({
  total: total.value,
  current: current.value,
  pageSize: pageSize.value
}))
// 物品数据
const dataSource = computed<ArticleDTO[]>(() => data.value?.data.data.records || [])

// 新增数据模态框是否可见
const modalVisible = ref<boolean>(false)
const addFormRef = ref<FormInstance>()
// 新增表单
const addFormState = ref<AddArticleDTO>({
  name: '',
  leasingPrice: 0.0,
  description: '',
  status: 0,
  categoryId: 1,
  imgList: []
})

const handleOk = () => {
  addArticle(addFormState.value).then((res) => {
    const { code, msg } = res.data
    message.success(msg)
    if (code == 200) {
      addFormRef.value?.resetFields()
      modalVisible.value = false
      fileList.value = []
      run({
        current: pagination.value.current,
        pageSize: pagination.value.pageSize,
        ...queryFormState
      })
    }
  })
}

const handleCancel = () => {
  addFormRef.value?.resetFields()
  fileList.value = []
}

const addFormRules: Record<string, Rule[]> = {
  name: [{ required: true, message: '物品名不能为空' }],
  leasingPrice: [{ required: true, message: '请输入租赁价格' }]
}

// 抽屉是否可见
const drawerVisible = ref<boolean>(false)
const updateFormRef = ref<FormInstance>()
// 更新表单
const updateFormState = ref<UpdateArticleDTO>({
  id: 0,
  name: '',
  description: '',
  status: 0,
  leasingPrice: 0,
  categoryId: 1,
  imgList: []
})

const updateFormRules: Record<string, Rule[]> = {
  name: [{ required: true, message: '物品名不能为空' }],
  categoryId: [{ required: true, message: '请选择分类' }]
}

// 编辑
const onEdit = (id: number) => {
  getArticleById(id).then((res) => {
    const { data } = res.data
    updateFormState.value = {
      id: data.id,
      name: data.name,
      description: data.description,
      leasingPrice: data.leasingPrice,
      status: data.status,
      categoryId: data.categoryId,
      imgList: data.imgList
    }
    if (data.imgList) {
      data.imgList.forEach((img, index) => {
        fileList.value?.push({
          uid: (0 - index).toString(),
          name: data.name + '图片' + index,
          url: img,
          status: 'done'
        })
      })
    }
  })
  showDrawer()
}
// 打开抽屉
const showDrawer = () => {
  drawerVisible.value = true
}
// 关闭抽屉
const onClose = () => {
  drawerVisible.value = false
  updateFormRef.value?.resetFields()
  fileList.value = []
}

// 提交编辑
const onFinish = () =>
  updateArticle(updateFormState.value).then((res) => {
    const { code, msg } = res.data
    message.success(msg)
    if (code == 200) {
      onClose()
      run({
        current: pagination.value.current,
        pageSize: pagination.value.pageSize,
        ...queryFormState
      })
    }
  })

/**
 * ===============================删除==================================
 */
const idList = ref<number[]>([])
// 删除
const onDelete = (id: number) => {
  idList.value = [id]
}
const confirm = () => {
  if (idList.value.length > 0) {
    deleteByIds(idList.value).then((res) => {
      const { code, msg } = res.data
      if (code == 200) {
        message.success(msg)
        run({
          current: pagination.value.current,
          pageSize: pagination.value.pageSize,
          ...queryFormState
        })
      }
    })
  }
}
type Key = string | number
const rowSelectionState = reactive<{
  selectedRowKeys: Key[]
  loading: boolean
}>({
  selectedRowKeys: [],
  loading: false
})

const hasSelected = computed(() => rowSelectionState.selectedRowKeys.length > 0)
const { selectedRowKeys } = toRefs(rowSelectionState)
const onSelectChange = (selectedRowKeys: Key[]) => {
  rowSelectionState.selectedRowKeys = selectedRowKeys
}
const start = () => {
  rowSelectionState.loading = true
  deleteByIds(rowSelectionState.selectedRowKeys).then((res) => {
    const { code, msg } = res.data
    if (code == 200) {
      rowSelectionState.loading = false
      rowSelectionState.selectedRowKeys = []
      message.success(msg)
      run({ current: pagination.value.current, pageSize: pagination.value.pageSize })
    }
  })
}

// 图片上传
const uploadLoading = ref(false)
const fileList = ref<UploadFile[]>([])

const handleChange = (info: UploadChangeParam) => {
  const file = info.file
  if (file.status === 'uploading') {
    uploadLoading.value = true
    return
  }
  if (file.status === 'done') {
    file.url = file.response.url
    updateFormState.value.imgList.push(file.response.url)
    addFormState.value.imgList.push(file.response.url)
    uploadLoading.value = false
    message.success('上传成功')
  }
  if (file.status === 'error') {
    uploadLoading.value = false
    message.error('上传错误')
  }
}

const handleRemove = (file: UploadFile) => {
  updateFormState.value.imgList = updateFormState.value.imgList.filter((img) => {
    return img !== file.url
  })
  addFormState.value.imgList = addFormState.value.imgList.filter((img) => {
    return img !== file.url
  })
}
</script>
<style lang="less" scoped>
.action {
  button:first-child {
    margin-right: 5px;
  }

  button:last-child {
    margin-left: 5px;
  }
}

.disabled,
.enable {
  display: flex;
  justify-content: center;
  font-size: 12px;
}

.disabled::before {
  content: '';
  width: 8px;
  height: 8px;
  background-color: red;
  margin: auto 2px auto 0;
}

.disabled::after {
  content: '下架或已租出';
  margin: auto 2px auto 0;
}

.enable::before {
  content: '';
  width: 8px;
  height: 8px;
  background-color: green;
  margin: auto 2px auto 0;
}

.enable::after {
  content: '上架中';
  margin: auto 2px auto 0;
}

.ant-upload-select-picture-card i {
  font-size: 32px;
  color: #999;
}

.ant-upload-select-picture-card .ant-upload-text {
  margin-top: 8px;
  color: #666;
}
</style>